Jx.declare('Jx.lib.Operation', {
	
	$extend: 'Jx.lib.Configurable',
	
	$accessors: {
		
		successful: false,
		
		completed: false
		
	},
	
	$actions: [
		
		'setError'
		
	],
	
	errors: undefined,
	
	errorCodes: {
		
		1: 'Unknown'
		
	},
	
	defaultErrorCode: 1,
	
	constructor: function(){
		
		this.errors = [];
		
		this.$super();
		
	},
	
	onSetCompleted: function(){
		
		this.set('completed', true);
		
	},
	
	onSetError: function(operation){
		
		this.errors.push(
			
			operation.errorObject = {
			
				code: operation.code,
				
				message: operation.message
				
			}
			
		);
		
	},
	
	onAfterSetError: function(operation){
		
		this.set('successful', false);
		
	},
	
	allowSetSuccessful: function(operation, succeeded){
		
		return this.completed() &&
			
			this.errors.length == 0 &&
			
			Jx.isBoolean( succeeded );
		
	},
	
	allowSetCompleted: function(operation, completed){
		
		return completed !== false;
		
	},
	
	allowSetError: function(operation, code, message){
		
		if (Jx.isString(code, true)){
			
			message = code;
			
			code = this.defaultErrorCode;
			
		}
		
		operation.code = code;
		
		operation.message = message;
		
		return Jx.isNumber(code) &&
			
			code in this.errorCodes &&
			
			Jx.isString(message, true);
		
	},
	
	getError: function(filterCodes){
		
		var errors = this.errors,
		
			codes = this.errorCodes,
			
			found = [],
			
			hasFilter;
		
		if (!Jx.isArray(filterCodes)){
			
			filterCodes = Array.prototype.slice.call(arguments, 0);
			
		}
		
		for(var error, code, hasFilter = filterCodes.length, l = errors.length; l--;){
			
			error = errors[l];
			
			code = error.code;
			
			if (!hasFilter || filterCodes.indexOf(code) != -1){
				
				found[l] = '[ '+ code +': ' + codes[code]+ ' ] '+ error.message;
				
			} else {
				
				found.splice(l, 1);
				
			}
			
		}
		
		return found;
		
	}
	
	
});
